import { BuilderHTMLElement } from '@farris/designer-element';
import FdContainerBaseComponent from '../../common/containerBase/containerBase';
import { DgControl } from '../../../../utils/dg-control';
import { DesignViewModelService, SchemaService, DomService, ComponentResolveContext, FormBindingType } from '@farris/designer-services';
import { FormDragDropManager } from '../../form/drag-drop/dragAndDropManager';

export class FieldSetDragDropManager {

    private cmpInstance: FdContainerBaseComponent;

    constructor(cmpInstance: FdContainerBaseComponent) {
        this.cmpInstance = cmpInstance;
    }
    /**
     * 判断是否可以接收拖拽新增的子级控件
     * @returns boolean
     */
    canAccepts(sourceElement: BuilderHTMLElement) {
        const serviceHost = this.cmpInstance.options.designerHost;
        const domService = serviceHost.getService('DomService') as DomService;
        const dragResolveService = serviceHost.getService('DragResolveService');
        const resolveContext = dragResolveService.getComponentResolveContext(sourceElement, this) as ComponentResolveContext;

        // 只接收输入类控件
        if (resolveContext.controlCategory !== 'input') {
            return false;
        }
        // 实体树中拖拽来的字段，需要判断是否属于当前组件绑定的实体
        if (resolveContext.sourceType === 'field') {
            const schemaService = serviceHost.getService('SchemaService') as SchemaService;
            const fieldInfo = schemaService.getFieldByIDAndVMID(resolveContext.bindingTargetId, this.cmpInstance.viewModelId);
            if (!fieldInfo || !fieldInfo.schemaField) {
                return false;
            }
        }

        // 在现有设计器中拖拽控件：跨Component的移动，需要判断组件是否绑定同一实体。
        const sourceComponentInstance = sourceElement.componentInstance;
        if (sourceComponentInstance && sourceComponentInstance.viewModelId !== this.cmpInstance.viewModelId) {
            const sourceVM = domService.getViewModelById(sourceComponentInstance.viewModelId);
            const currentVM = domService.getViewModelById(this.cmpInstance.viewModelId);
            return sourceVM.bindTo === currentVM.bindTo;
        }
        return true;
    }




    /**
     * 移动控件后事件：在可视化设计器中，将现有的控件移动到容器中
     * @param el 移动的源DOM结构
     */
    onAcceptMovedChildElement(sourceElement: BuilderHTMLElement) {
        if (!sourceElement) {
            return;
        }

        const sourceComponentInstance = sourceElement.componentInstance;
        if (!sourceComponentInstance) {
            return;
        }
        const sourceComponentSchema = sourceComponentInstance.component;
        if (!sourceComponentSchema.binding || !sourceComponentSchema.binding.field) {
            return;
        }

        const serviceHost = this.cmpInstance.options.designerHost;
        const domService = serviceHost.getService('DomService') as DomService;
        const dgViewModelService = serviceHost.getService('DesignViewModelService') as DesignViewModelService;
        const sourceDgViewModel = dgViewModelService.getDgViewModel(sourceComponentInstance.viewModelId);

        // 若从另外一个fieldSet移动到当前fieldSet；或者从Form移动到当前fieldSet，都需要变更VM中的分组信息
        const sourceParentComponent = sourceComponentInstance.parent;
        switch (sourceParentComponent && sourceParentComponent.type) {
            case DgControl.FieldSet.type: case DgControl.Form.type: {
                const changeSet = { groupId: this.cmpInstance.component.id, groupName: this.cmpInstance.component.title };
                const sourceBindingType = sourceComponentSchema.binding.type;
                switch (sourceBindingType) {
                    case FormBindingType.Form: {
                        sourceDgViewModel.changeField(sourceComponentSchema.binding.field, changeSet);
                        break;
                    }
                    case FormBindingType.Variable: {
                        domService.modifyViewModelFieldById(sourceComponentInstance.viewModelId, sourceComponentSchema.binding.field, changeSet, true);
                        break;
                    }
                }
                break;
            }
        }

        // 若是跨组件的移动，需要移动vm的字段
        if (sourceComponentInstance.viewModelId !== this.cmpInstance.viewModelId) {
            const formMoveHandler = new FormDragDropManager(this.cmpInstance);
            formMoveHandler.moveInputBetweenComponent(sourceComponentSchema, sourceComponentInstance.viewModelId);

        }

    }

}
